package com.jack.cms.oss.core;

import java.awt.Container;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;



/*** 缩略图实现，将图片(jpg、bmp、png、gif等等)真实的变成想要的大小 */

@Service("talUploadService")
public class TalUploadService {

	/*******************************************************************************
	 * 缩略图类（通用）本java类能将jpg、bmp,png,gif,图片文件，进行等比或非等比的大小转换。具体使用方法compressPic(
	 * 大图片路径,生成小图片路径 ,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
	 */

	public static class CompressPicDemo {

		private static final Logger logger = LoggerFactory.getLogger(CompressPicDemo.class);

//		private File file = null; // 文件对象
		private String inputDir; // 输入图路径
		private String outputDir; // 输出图路径
		private String inputFileName; // 输入图文件名
		private String outputFileName; // 输出图文件名
		private int outputWidth = 100; // 默认输出图片宽
		private int outputHeight = 100; // 默认输出图片高
		private boolean proportion = true; // 是否等比缩放标记(默认为等比缩放)

		public CompressPicDemo() { // 初始化变量
			inputDir = "";
			outputDir = "";
			inputFileName = "";
			outputFileName = "";
			outputWidth = 100;
			outputHeight = 100;
		}

		public void setInputDir(String inputDir) {
			this.inputDir = inputDir;
		}

		public void setOutputDir(String outputDir) {
			this.outputDir = outputDir;
		}

		public void setInputFileName(String inputFileName) {
			this.inputFileName = inputFileName;
		}

		public void setOutputFileName(String outputFileName) {
			this.outputFileName = outputFileName;
		}

		public void setOutputWidth(int outputWidth) {
			this.outputWidth = outputWidth;
		}

		public void setOutputHeight(int outputHeight) {
			this.outputHeight = outputHeight;
		}

		public void setWidthAndHeight(int width, int height) {
			this.outputWidth = width;
			this.outputHeight = height;
		}

		/*
		 * 获得图片大小 传入参数String path ：图片路径
		 */

		public long getPicSize(File file) {
			return file.length();
		}

		// 图片处理
		public String compressPic(File file) {
			try {
				// 获得源文件
				ImageInputStream input = ImageIO.createImageInputStream(file);
			
				Iterator<?> readers = ImageIO.getImageReaders(input);
				if (readers == null || !readers.hasNext()) {
					throw new RuntimeException("1 No ImageReaders found");
				}
				ImageReader reader = (ImageReader) readers.next();
				reader.setInput(input);
				BufferedImage img;

				try {
					img = ImageIO.read(file); // 这里是从本地读图片文件，如果是执行上传图片的话，Formfile
												// formfile=获得表单提交的Formfile
												// ,然后ImageIO.read
												// 方法里参数放formfile.getInputStream()
				} catch (Exception ex) {
					// 读取Raster (没有颜色的转换).
					logger.info("异常信息为:" + ex.getMessage());
					Raster raster = reader.readRaster(0, null);// CMYK
					img = createJPEG4(raster);
				}

				// 判断图片格式是否正确
				if (img.getWidth(null) == -1) {
					System.out.println(" can't read,retry!" + "<BR>");
					return "no";
				} else {
					int newWidth;
					int newHeight;
					// 判断是否是等比缩放
					if (this.proportion == true) {
						// 为等比缩放计算输出的图片宽度及高度
						double rate1 = ((double) img.getWidth(null))
								/ (double) outputWidth + 0.1;
						double rate2 = ((double) img.getHeight(null))
								/ (double) outputHeight + 0.1;
						// 根据缩放比率大的进行缩放控制
						double rate = rate1 > rate2 ? rate1 : rate2;
						newWidth = (int) (((double) img.getWidth(null)) / rate);
						newHeight = (int) (((double) img.getHeight(null)) / rate);
					} else {
						newWidth = outputWidth; // 输出的图片宽度
						newHeight = outputHeight; // 输出的图片高度
					}
					BufferedImage tag = new BufferedImage((int) newWidth,
							(int) newHeight, BufferedImage.TYPE_INT_RGB);
					/*
					 * Image.SCALE_SMOOTH 的缩略算法生成缩略图片的平滑度的 优先级比速度高生成的图片质量比较好但速度慢
					 */
					tag.getGraphics().drawImage(
							img.getScaledInstance(newWidth, newHeight,
									Image.SCALE_SMOOTH), 0, 0, null);

					FileOutputStream out = new FileOutputStream(outputDir
							+ outputFileName);

					// JPEGImageEncoder可适用于其他图片类型的转换
					// JPEGImageEncoder encoder =
					// JPEGCodec.createJPEGEncoder(out);
					// encoder.encode(tag);

					ImageIO.write(tag, "jpg", out);
					out.close();
				}
			} catch (IOException ex) {
				// ex.printStackTrace();
				try {
					// 获得源文件
					file = new File(inputDir + inputFileName);
					if (!file.exists()) {
						return "";
					}
					ThumbnailConvert tc = new ThumbnailConvert();
					tc.setCMYK_COMMAND(file.getPath());
					Image image = Toolkit.getDefaultToolkit().getImage(
							file.getPath());
					MediaTracker mediaTracker = new MediaTracker(
							new Container());
					mediaTracker.addImage(image, 0);
					mediaTracker.waitForID(0);
					image.getWidth(null);
					image.getHeight(null);
				} catch (Exception e1) {
                    logger.info("异常信息为:" + e1.getMessage());
				}
			}
			return "ok";
		}

		public String compressPic(String inputDir, String outputDir,
				String inputFileName, String outputFileName, File file) {
			// 输入图路径
			this.inputDir = inputDir;
			// 输出图路径
			this.outputDir = outputDir;
			// 输入图文件名
			this.inputFileName = inputFileName;
			// 输出图文件名
			this.outputFileName = outputFileName;
			return compressPic(file);
		}

		public String compressPic(String inputDir, String outputDir,
				String inputFileName, String outputFileName, int width,
				int height, boolean gp, File file) {
			// 输入图路径
			this.inputDir = inputDir;
			// 输出图路径
			this.outputDir = outputDir;
			// 输入图文件名
			this.inputFileName = inputFileName;
			// 输出图文件名
			this.outputFileName = outputFileName;
			// 设置图片长宽
			setWidthAndHeight(width, height);
			// 是否是等比缩放标记
			this.proportion = gp;
			return compressPic(file);
		}

		private static BufferedImage createJPEG4(Raster raster) {
			int w = raster.getWidth();
			int h = raster.getHeight();
			byte[] rgb = new byte[w * h * 3];
			// 彩色空间转换
			float[] Y = raster.getSamples(0, 0, w, h, 0, (float[]) null);
			float[] Cb = raster.getSamples(0, 0, w, h, 1, (float[]) null);
			float[] Cr = raster.getSamples(0, 0, w, h, 2, (float[]) null);
			float[] K = raster.getSamples(0, 0, w, h, 3, (float[]) null);

			for (int i = 0, imax = Y.length, base = 0; i < imax; i++, base += 3) {
				float k = 220 - K[i], y = 255 - Y[i], cb = 255 - Cb[i], cr = 255 - Cr[i];

				double val = y + 1.402 * (cr - 128) - k;
				val = (val - 128) * .65f + 128;
				rgb[base] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
						: (byte) (val + 0.5);

				val = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128) - k;
				val = (val - 128) * .65f + 128;
				rgb[base + 1] = val < 0.0 ? (byte) 0
						: val > 255.0 ? (byte) 0xff : (byte) (val + 0.5);

				val = y + 1.772 * (cb - 128) - k;
				val = (val - 128) * .65f + 128;
				rgb[base + 2] = val < 0.0 ? (byte) 0
						: val > 255.0 ? (byte) 0xff : (byte) (val + 0.5);
			}

			raster = Raster.createInterleavedRaster(new DataBufferByte(rgb,
					rgb.length), w, h, w * 3, 3, new int[] { 0, 1, 2 }, null);

			ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
			ColorModel cm = new ComponentColorModel(cs, false, true,
					Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
			return new BufferedImage(cm, (WritableRaster) raster, true, null);
		}

		/**
		 * 根据流进行缩放图片
		 * @param stream
		 * @return
		 * @throws IOException
		 */
		public ByteArrayOutputStream compressPic(InputStream stream ) throws IOException {
			ByteArrayOutputStream out = null;//返回字节流
			try {
				// 获得源文件
				ImageInputStream input =ImageIO.createImageInputStream(stream);
				//ImageInputStream input = ImageIO.createImageInputStream(file);
			
				Iterator<?> readers = ImageIO.getImageReaders(input);
				if (readers == null || !readers.hasNext()) {
					throw new RuntimeException("1 No ImageReaders found");
				}
				ImageReader reader = (ImageReader) readers.next();
				reader.setInput(input);
				BufferedImage img;
				img = ImageIO.read(input);
				
				// 判断图片格式是否正确
				if (img.getWidth(null) == -1) {
					System.out.println(" can't read,retry!" + "<BR>");
					return null;
				} else {
					int newWidth;
					int newHeight;
					// 判断是否是等比缩放
					if (this.proportion == true) {
						// 为等比缩放计算输出的图片宽度及高度
						double rate1 = ((double) img.getWidth(null))
								/ (double) outputWidth + 0.1;
						double rate2 = ((double) img.getHeight(null))
								/ (double) outputHeight + 0.1;
						// 根据缩放比率大的进行缩放控制
						double rate = rate1 > rate2 ? rate1 : rate2;
						newWidth = (int) (((double) img.getWidth(null)) / rate);
						newHeight = (int) (((double) img.getHeight(null)) / rate);
					} else {
						newWidth = outputWidth; // 输出的图片宽度
						newHeight = outputHeight; // 输出的图片高度
					}
					BufferedImage tag = new BufferedImage((int) newWidth,
							(int) newHeight, BufferedImage.TYPE_INT_RGB);
					/*
					 * Image.SCALE_SMOOTH 的缩略算法生成缩略图片的平滑度的 优先级比速度高生成的图片质量比较好但速度慢
					 */
					tag.getGraphics().drawImage(
							img.getScaledInstance(newWidth, newHeight,
									Image.SCALE_SMOOTH), 0, 0, null);

				

					// JPEGImageEncoder可适用于其他图片类型的转换
					// JPEGImageEncoder encoder =
					// JPEGCodec.createJPEGEncoder(out);
					// encoder.encode(tag);
					 out = new ByteArrayOutputStream();
					//ImageIO.write(tag, formatName, output);
					ImageIO.write(tag, "jpg", out);
					out.close();
				}
			} catch (IOException ex) {
				throw ex;
			}
			return out;
		}

	}
	
	
	public static void main(String[] args) {
		//保存媒体图片部分
//		File file 
//		CompressPicDemo  compressService = new CompressPicDemo();
//		compressService.setWidthAndHeight(100, 80);
//		ByteArrayOutputStream bos = compressService.compressPic(stream);
//		FileOutputStream out = new FileOutputStream(outputDir
//				+ outputFileName);
//
//		// JPEGImageEncoder可适用于其他图片类型的转换
//		// JPEGImageEncoder encoder =
//		// JPEGCodec.createJPEGEncoder(out);
//		// encoder.encode(tag);
//
//		ImageIO.write(tag, "jpg", out);
//		out.close();
	}

}
